using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Http;

namespace CKY.AgentPlatform.ModelConfigs
{
    /// <summary>
    /// 增强的OpenAI兼容适配器
    /// </summary>
    public class EnhancedOpenAIAdapter : EnhancedModelAdapterBase
    {
        public EnhancedOpenAIAdapter(
            ILogger<EnhancedModelAdapterBase> logger,
            ModelCircuitBreaker circuitBreaker,
            ModelMonitoringService monitoringService,
            IHttpClientFactory httpClientFactory) : base(logger, circuitBreaker, monitoringService, httpClientFactory)
        {
        }

        public override ModelApiMode SupportedMode => ModelApiMode.OpenAICompatible;
        public override ModelProvider SupportedProvider => ModelProvider.Custom;
        public override string Name => "Enhanced OpenAI Compatible Adapter";
        public override string Version => "2.0.0";
        public override bool SupportsStreaming => true;
        public override bool SupportsToolCalling => true;

        protected override async Task<ModelInvocationResponse> ExecuteInternalAsync(
            ModelInvocationConfig config,
            ModelInvocationRequest request,
            string executionId)
        {
            try
            {
                var startTime = DateTime.UtcNow;

                // 构建请求
                var openAIRequest = BuildOpenAIRequest(request);
                var requestContent = BuildJsonContent(openAIRequest);

                // 设置认证头
                var apiKey = config.ModelSpecificParams["ApiKey"].ToString();
                config.CustomHeaders["Authorization"] = $"Bearer {apiKey}";

                // 发送请求
                var response = await SendHttpRequestAsync(
                    config,
                    HttpMethod.Post,
                    config.OpenAICompatibleEndpoint,
                    requestContent,
                    TimeSpan.FromSeconds(30)
                );

                var responseContent = await response.Content.ReadAsStringAsync();
                var responseTime = (long)(DateTime.UtcNow - startTime).TotalMilliseconds;

                // 处理HTTP错误
                if (!response.IsSuccessStatusCode)
                {
                    var errorResponse = new ErrorResponse
                    {
                        Code = $"HTTP_{(int)response.StatusCode}",
                        Message = $"OpenAI API调用失败: {response.StatusCode}",
                        Type = "HttpError",
                        Param = new Dictionary<string, object>
                        {
                            ["statusCode"] = (int)response.StatusCode,
                            ["responseContent"] = responseContent
                        }
                    };

                    return new ModelInvocationResponse
                    {
                        Error = errorResponse,
                        UsedApiMode = SupportedMode,
                        ResponseTimeMs = responseTime
                    };
                }

                // 解析成功响应
                var result = ParseOpenAIResponse(responseContent);
                result.ResponseTimeMs = responseTime;
                result.UsedApiMode = SupportedMode;

                return result;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"OpenAI兼容适配器调用失败: {ex.Message}", ex);
            }
        }

        public override bool ValidateConfig(ModelInvocationConfig config)
        {
            if (!base.ValidateConfig(config))
                return false;

            return !string.IsNullOrWhiteSpace(config.OpenAICompatibleEndpoint) &&
                   config.ModelSpecificParams.ContainsKey("ApiKey");
        }

        public override AdapterCapabilities GetCapabilities()
        {
            return new AdapterCapabilities
            {
                Description = "增强的OpenAI兼容模式适配器，支持完整的错误处理、熔断和监控功能",
                SupportedModels = new List<string>
                {
                    "gpt-4", "gpt-4-turbo", "gpt-4o", "gpt-3.5-turbo", "gpt-3.5-turbo-16k",
                    "claude-3-haiku-20240307", "claude-3-sonnet-20240229",
                    "glm-4", "glm-4-air", "glm-4-flash", "glm-3-turbo"
                },
                MaxInputLength = 128000,
                MaxOutputLength = 4096,
                SupportedParameters = new List<string>
                {
                    "temperature", "max_tokens", "top_p", "frequency_penalty",
                    "presence_penalty", "stop", "stream", "tools", "tool_choice"
                },
                SpecialRequirements = new Dictionary<string, string>
                {
                    { "format", "请求格式必须符合OpenAI API规范" },
                    { "auth", "使用Bearer Token进行认证" },
                    { "retry", "支持自动重试和熔断保护" },
                    { "monitoring", "完整的执行监控和性能指标" }
                }
            };
        }

        /// <summary>
        /// 构建OpenAI请求
        /// </summary>
        private object BuildOpenAIRequest(ModelInvocationRequest request)
        {
            var openAIRequest = new
            {
                model = request.Model,
                messages = request.Messages.Select(m => new
                {
                    role = m.Role,
                    content = m.Content
                }).ToList(),
                max_tokens = request.MaxTokens,
                temperature = request.Temperature,
                top_p = request.TopP,
                stream = request.Stream,
                stop = request.Stop,
                frequency_penalty = request.FrequencyPenalty,
                presence_penalty = request.PresencePenalty
            };

            // 添加工具调用支持
            if (request.Tools?.Any() == true)
            {
                var tools = request.Tools.Select(t => new
                {
                    type = t.Type,
                    function = new
                    {
                        name = t.Function.Name,
                        description = t.Function.Description,
                        parameters = t.Function.Parameters
                    }
                }).ToList();

                // 使用动态类型添加tools属性
                var requestDict = new System.Dynamic.ExpandoObject() as IDictionary<string, object>;
                foreach (var prop in openAIRequest.GetType().GetProperties())
                {
                    requestDict[prop.Name] = prop.GetValue(openAIRequest);
                }
                requestDict["tools"] = tools;

                // 如果有tool_choice配置也添加
                if (request.Metadata?.TryGetValue("tool_choice", out var toolChoice) == true)
                {
                    requestDict["tool_choice"] = toolChoice;
                }

                return requestDict;
            }

            return openAIRequest;
        }

        /// <summary>
        /// 解析OpenAI响应
        /// </summary>
        private ModelInvocationResponse ParseOpenAIResponse(string responseContent)
        {
            try
            {
                var root = ParseJsonResponse(responseContent);
                var response = new ModelInvocationResponse();

                // 基本信息
                if (root.TryGetProperty("id", out var idProp))
                    response.Id = idProp.GetString();

                if (root.TryGetProperty("object", out var objectProp))
                    response.Object = objectProp.GetString();

                if (root.TryGetProperty("created", out var createdProp))
                    response.Created = DateTime.UnixEpoch.AddSeconds(createdProp.GetInt64());

                if (root.TryGetProperty("model", out var modelProp))
                    response.Model = modelProp.GetString();

                // 解析响应消息
                if (root.TryGetProperty("choices", out var choicesProp) &&
                    choicesProp.ValueKind == System.Text.Json.JsonValueKind.Array &&
                    choicesProp.GetArrayLength() > 0)
                {
                    var firstChoice = choicesProp.EnumerateArray().First();

                    if (firstChoice.TryGetProperty("message", out var messageProp))
                    {
                        var responseMessage = new ResponseMessage();

                        if (messageProp.TryGetProperty("role", out var roleProp))
                            responseMessage.Role = roleProp.GetString();

                        if (messageProp.TryGetProperty("content", out var contentProp))
                            responseMessage.Content = contentProp.GetString() ?? "";

                        // 解析工具调用
                        if (messageProp.TryGetProperty("tool_calls", out var toolCallsProp))
                        {
                            responseMessage.ToolCalls = ParseToolCalls(toolCallsProp);
                        }

                        response.Response = responseMessage;
                    }

                    // 解析完成原因
                    if (firstChoice.TryGetProperty("finish_reason", out var finishReasonProp))
                    {
                        response.Metadata ??= new Dictionary<string, object>();
                        response.Metadata["finish_reason"] = finishReasonProp.GetString();
                    }
                }

                // 解析使用统计
                if (root.TryGetProperty("usage", out var usageProp))
                {
                    response.Usage = new UsageInfo();

                    if (usageProp.TryGetProperty("prompt_tokens", out var promptTokensProp))
                        response.Usage.PromptTokens = promptTokensProp.GetInt32();

                    if (usageProp.TryGetProperty("completion_tokens", out var completionTokensProp))
                        response.Usage.CompletionTokens = completionTokensProp.GetInt32();

                    if (usageProp.TryGetProperty("total_tokens", out var totalTokensProp))
                        response.Usage.TotalTokens = totalTokensProp.GetInt32();
                }

                return response;
            }
            catch (System.Text.Json.JsonException ex)
            {
                var errorInfo = ModelErrorClassifier.ClassifyJsonException(ex, new ModelErrorInfo());
                throw new InvalidOperationException($"解析OpenAI响应失败: {errorInfo.ErrorMessage}", ex);
            }
        }

        /// <summary>
        /// 解析工具调用
        /// </summary>
        private List<ToolCall> ParseToolCalls(System.Text.Json.JsonElement toolCallsElement)
        {
            var toolCalls = new List<ToolCall>();

            foreach (var toolCallElement in toolCallsElement.EnumerateArray())
            {
                if (toolCallElement.TryGetProperty("function", out var functionProp))
                {
                    var toolCall = new ToolCall
                    {
                        Id = toolCallElement.TryGetProperty("id", out var idProp) ? idProp.GetString() : "",
                        Type = toolCallElement.TryGetProperty("type", out var typeProp) ? typeProp.GetString() : "function",
                        FunctionName = functionProp.TryGetProperty("name", out var nameProp) ? nameProp.GetString() : ""
                    };

                    // 解析函数参数
                    if (functionProp.TryGetProperty("arguments", out var argumentsProp))
                    {
                        try
                        {
                            var argumentsJson = argumentsProp.GetString() ?? "{}";
                            toolCall.FunctionArguments = JsonSerializer.Deserialize<Dictionary<string, object>>(argumentsJson);
                        }
                        catch
                        {
                            toolCall.FunctionArguments = new Dictionary<string, object>();
                        }
                    }

                    toolCalls.Add(toolCall);
                }
            }

            return toolCalls;
        }
    }
}